package com.aps.common.model.genetic;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author jsy
 * @description:在APS排程系统中，工序是生产流程的基本执行单元，每个订单包含多个工序，每个工序有自己的处理时间和顺序。
 * @date 2025/9/11 20:05
 */
@Schema(description = "订单工序")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OrderProcess implements Serializable {
    /**
     * 工序ID
     */
    private String id;
    /**
     * 所属订单ID
     */
    private String orderId;
    /**
     * 工序名称
     */
    private String processName;
    /**
     * 工序处理时间（单位：分钟）
     */
    private double unitProcessingTime;
    /**
     * 工序准备时长（换线、换模、加料等）（单位：分钟）
     */
    private double operationPreparedTime;
    /**
     * 工序顺序（从1开始）
     */
    private int sequence;
    /**
     * 工序所属设备（类型）
     */
    private String equipmentType;
    /**
     * 工序时间区间列表
     */
    private List<ProcessInterval> processIntervalList = new ArrayList<>();  // 关键修改：初始化列表

    /**
     * 整个工序的开始时间（第一个产品开始加工的时间）
     * */
    private LocalDateTime startTime;

    /**
     * 整个工序的结束时间（最后一个产品完成加工的时间）
     * */
    private LocalDateTime endTime;
    /**
     * @description: 添加工序的时间区间列表
     * @author: jsy
     * @time: 2025/9/13 16:40
     */
    public void addProcessInterval(ProcessInterval processInterval) {
        if (processInterval == null) {
            throw new IllegalArgumentException("工序时间区间不能为空");
        }
        this.processIntervalList.add(processInterval);
        // 更新工序的整体开始和结束时间
        updateProcessTimeRange();
    }

    private void updateProcessTimeRange() {
        if (processIntervalList.isEmpty()) {
            this.startTime = null;
            this.endTime = null;
            return;
        }

        // 找到最早的开始时间和最晚的结束时间
        this.startTime = processIntervalList.stream()
                .map(ProcessInterval::getStartTime)
                .min(LocalDateTime::compareTo)
                .orElse(null);

        this.endTime = processIntervalList.stream()
                .map(ProcessInterval::getEndTime)
                .max(LocalDateTime::compareTo)
                .orElse(null);
    }

    public void resetAvailability() {
        this.processIntervalList.clear();
    }
}
